<template>
  <div>
    <div v-if="mode === 'DESIGN'">
      <draggable class="l-drag-from" item-key="id" v-model="_items"
                 :component-data="{tag: 'div', type: 'transition-group'}" v-bind="dragProps"
                 @start="drag = true; selectFormItem = null" @end="drag = false">
        <template #item="{element, index}">
          <div class="l-form-item" @click.stop="selectItem(element)" :style="getSelectedClass(element)">
            <div class="l-form-header">
              <p><span v-if="element.props.required">*</span>{{ element.title }}</p>
              <div class="l-option">
                <!-- <el-icon @click="copy"><CopyDocument /></el-icon> -->
                <el-icon @click="delItem(index)"><Close /></el-icon>
              </div>
              <form-design-render :config="element" />
            </div>
          </div>
        </template>

      </draggable>
      <div style="color: #c0bebe; text-align: center; width: 90%; padding: 5px">
        ☝ 拖拽控件到布局容器内部
      </div>
    </div>
    <div v-else-if="mode === 'PC' && !readonly">
      <el-row :gutter="20" v-for="(rows, rsi) in __items" :key="rsi + '_rows'">
        <el-col :span="24 / rows.length" v-for="(item, ri) in rows" :key="ri + '_row'">
          <el-form-item v-if="item.name !== 'SpanLayout' && item.name !== 'Description'" :prop="item.id" :label="item.title">
            <form-design-render :formData="formData" :readonly="isReadonly(item)" v-model="_value[item.id]" :mode="mode" :config="item"/>
          </el-form-item>
          <form-design-render :formData="formData" :readonly="isReadonly(item)" v-else v-model="_value" :mode="mode" :config="item"/>
        </el-col>
      </el-row>
    </div>
    <div v-else-if="mode === 'PC'">
      <div v-for="(item, rsi) in _items" :key="rsi + '_rows'" v-show="showItem(item)">
        <el-form-item v-if="item.name !== 'SpanLayout' && item.name !== 'Description'" :prop="item.id" :label="item.title">
          <form-design-render :formData="formData" :readonly="isReadonly(item)" v-model="_value[item.id]" :mode="mode" :config="item"/>
        </el-form-item>
        <form-design-render :formData="formData" :readonly="isReadonly(item)" v-else v-model="_value" :mode="mode" :config="item"/>
      </div>
    </div>
    <div v-else>
      <div v-for="(item, i) in _items" :key="'column_' + i" v-show="showItem(item)">
        <form-item v-if="item.name !== 'SpanLayout' && item.name !== 'Description'"
          :model="_value" :rule="rules[item.id]" :ref="setItemRef" :prop="item.id" :label="item.title">
          <form-design-render :formData="formData" :readonly="isReadonly(item)" v-model="_value[item.id]" :mode="mode" :config="item"/>
        </form-item>
        <form-design-render :formData="formData" :readonly="isReadonly(item)" v-else :ref="item.id" v-model="_value" :mode="mode" :config="item"/>
      </div>
    </div>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import { Close, CopyDocument } from '@element-plus/icons-vue'
import componentMinxins from '/@/views/setting/workflow/components/ComponentMinxins'
import FormItem from '/@/views/setting/workflow/common/FormItem.vue'
import FormDesignRender from '/@/views/setting/workflow/common/FormDesignRender.vue'
import { ValueType } from '/@/views/setting/workflow/config/ComponentsConfigExport'
import { computed, reactive, toRefs } from 'vue'
import { useWorkFlowConfig } from '/@/stores/workFlow'
import { storeToRefs } from 'pinia'
import { ElMessageBox } from 'element-plus'

export default {
    name: 'SpanLayout',
    components: { Close, CopyDocument, draggable, FormItem, FormDesignRender },
    mixins: [componentMinxins],
    props: {
        modelValue: {
            default: null,
        },
        items: {
            type: Array,
            default: () => {
                return []
            },
        },
        number: {
            type: Number,
            default: 2
        },
        formData: {
            type: Object,
            default: () => {
                return {}
            },
        },
    },
    emits: ['update:modelValue', 'update:items'],
    setup(props, context) {
        const { items, number, modelValue } = toRefs(props)
        const storesWorkFlowConfig = useWorkFlowConfig()
        const workFlowConfig = storeToRefs(storesWorkFlowConfig)
        let refs = []
        const state = reactive({
            select: null,
            drag: false,
            formConfig: {
                //数据字段
                data: {},
                //校验规则
                rules: {},
            },
            dragProps:{
                animation: 300,
                group: "form",
                disabled: false,
                sort: true,
                ghostClass: "choose",
            },
            form: {
                formId: '',
                formName: '',
                logo: {},
                formItems: [],
                process: {},
                remark: '',
            },
        })
        const setItemRef = el => {
            if (el) {
                refs.push(el)
            }
        }
        const _value = computed({
            get: () => {
                return modelValue.value
            },
            set: val => {
                context.emit('update:modelValue', val)
            }
        })
        const rules = computed(() => {
            let rules = {}
            items.value.forEach((v) => {
                if (v.props.required) {
                rules[v.id] = [
                    {
                    type: ValueType.getValidType(v.valueType),
                    required: true,
                    message: '请完成' + v.title,
                    trigger: 'blur' },
                ]
                }
            })
            return rules
        })
        const _items = computed({
            get: () => {
                return items.value
            },
            set: val => {
                context.emit('update:items', val)
            }
        })
        const __items = computed(() => {
            let result = []
            for (let i = 0; i < items.value.length; i++) {
                if (i > 0 && i % number.value === 0) {
                    result.push([items.value[i]])
                }else {
                    let row = result[parseInt(i / number.value)]
                    if (row){
                        row.push(items.value[i])
                    }else {
                        result.push([items.value[i]])
                    }
                }
            }
            return result
        })
        const selectFormItem = computed({
            get: () => {
                return workFlowConfig.selectFormItem.value
            },
            set: val => {
                storesWorkFlowConfig.setSelectForm(val)
                return true
            }
        })
        const nodeMap = computed(() => {
            return workFlowConfig.nodeMap.value
        })
        const showItem = (item) => {
            return (
                !(isReadonly(item) && isBlank(_value.value[item.id])) ||
                item.name === 'SpanLayout'
            )
        }
        const isBlank = (val) => {
            return (
                !isNotEmpty(val) ||
                (val instanceof String && val.trim() === '') ||
                (Array.isArray(val) && val.length === 0)
            )
        }
        const isReadonly = (item) => {
            return item.perm === 'R'
        }
        const selectItem = (cp) => {
            selectFormItem.value = cp
        }
        const getSelectedClass = (cp) => {
            return selectFormItem.value && selectFormItem.value.id === cp.id
                ? 'border-left: 4px solid #f56c6c'
                : ''
        }
        const delItem = (index) => {
            ElMessageBox.confirm(
                '删除组件将会连带删除包含该组件的条件以及相关设置，是否继续?',
                '提示',
                {
                    confirmButtonText: '确 定',
                    cancelButtonText: '取 消',
                    type: 'warning',
                }
            ).then(() => {
                if (_items.value[index].name === 'SpanLayout') {
                    //删除的是分栏则遍历删除分栏内所有子组件
                    _items.value[index].props.items.forEach((item) => {
                        removeFormItemAbout(item)
                    })
                    _items.value[index].props.items.length = 0
                } else {
                    removeFormItemAbout(_items.value[index])
                }
                _items.value.splice(index, 1)
            })
        }
        const validate = () => {
            let success = true
            items.value.forEach((form) => {
                let formRef = refs.find(item => item.id == form.id)
                if (formRef && Array.isArray(formRef) && formRef.length > 0) {
                    formRef[0].validate((subValid) => {
                        if (!subValid) {
                            success = false
                        }
                    })
                }
            })
            call(success)
        }
        const removeFormItemAbout = async (item) => {
            nodeMap.value.forEach((node) => {
                //搜寻条件，进行移除
                if (node.type === 'CONDITION') {
                    node.props.groups.forEach((group) => {
                        let i = group.cids.remove(item.id)
                        if (i > -1) {
                            //从子条件移除
                            group.conditions.splice(i, 1)
                        }
                    })
                }
                //搜寻权限，进行移除
                if (
                    node.type === 'ROOT' ||
                    node.type === 'APPROVAL' ||
                    node.type === 'CC'
                ) {
                    // node.props.formPerms.removeByKey('id', item.id)
                    const index = node.props.formPerms.findIndex((value) => value[id] === item.id)
                    if (index > -1) {
                      node.props.formPerms.splice(index, 1)
                    }
                }
            })
        }
        return {
            ...toRefs(state),
            rules,
            _items,
            __items,
            selectFormItem,
            nodeMap,
            Close, 
            CopyDocument,
            showItem,
            isBlank,
            isReadonly,
            selectItem,
            getSelectedClass,
            delItem,
            validate,
            setItemRef,
            _value
        }
    }
}
</script>

<style lang="scss" scoped> 
.choose {
  border: 1px dashed var(--el-color-primary) !important;
}
.l-drag-from {
  min-height: 50px;
  background-color: rgb(245, 246, 246);
  .l-form-item,
  li {
    cursor: grab;
    background: #ffffff;
    padding: 10px;
    border: 1px solid #ebecee;
    margin: 5px 0;
  }
}
.l-form-header {
  font-size: small;
  color: #818181;
  text-align: left;
  position: relative;
  background-color: #fff;
  p {
    position: relative;
    margin: 0 0 10px 0;

    span {
      position: absolute;
      left: -8px;
      top: 3px;
      color: rgb(217, 0, 19);
    }
  }

  .l-option {
    position: absolute;
    top: -10px;
    right: -10px;

    :deep(.icon) {
      font-size: large;
      cursor: pointer;
      color: #8c8c8c;
      padding: 5px;

      &:hover {
        color: var(--el-color-primary);
      }
    }
  }
}
</style>